//-----------------------------------------------------------------------------
//  Copyright (c) 2013 by HangZhou HenqgQiao Design Corporation. All rights reserved.
//
//  Project  : 
//  Module   : over sample the input data with 8-phases 311M clock
//  Parent   : 
//  Children : 
//
//  Description: 
//
//  Parameters:
//  Local Parameters:
//
//  Notes       : 
//
//  Multicycle and False Paths

module	FRM_TOP(
   input                         FRM_RESET,
   input                         FRM_RXCLK,
   input                         FRM_TXCLK,

   input                         MPI_CLK,
   input[7:0]                    MPI_ADDR,
   input                         MPI_CS,
   input                         MPI_WE,
   input[15:0]                   MPI_WD,
   output[15:0]                  MPI_RD,
   output                        MPI_IRQ,

   input[7:0]                    LINF_IN_RXD,
   input                         LINF_IN_RXDEN,

   output reg[7:0]               FRM_OUT_RDATA,
   output reg                    FRM_OUT_RDEN,
   output reg[1:0]               FRM_OUT_RFMCNT4,
   output reg[8:0]               FRM_OUT_RFMCNT270,
   output reg[3:0]               FRM_OUT_RFMCNT9,

   output[7:0]                   LINF_OUT_TXD,
 
   input[7:0]                    FRM_IN_TDATA,
   input[1:0]                    FRM_IN_TFMCNT4,
   input[8:0]                    FRM_IN_TFMCNT270,
   input[3:0]                    FRM_IN_TFMCNT9,

   input                         GLBCF_LINF_MODE
   );


wire[1:0]                        DELMT4_FMCNT4;
wire[8:0]                        DELMT4_FMCNT270;
wire[3:0]                        DELMT4_FMCNT9;
wire[7:0]                        DELMT4_DATA;
wire                             DELMT4_DEN;
wire                             DELMT4_OOF;

wire[8:0]                        DELMT1_FMCNT270;
wire[3:0]                        DELMT1_FMCNT9;
wire[7:0]                        DELMT1_DATA;
wire                             DELMT1_DEN;
wire                             DELMT1_OOF;

wire[7:0]                        RSCRM4_DATA;
wire                             RSCRM4_DEN;
wire[1:0]                        RSCRM4_FMCNT4;
wire[8:0]                        RSCRM4_FMCNT270;
wire[3:0]                        RSCRM4_FMCNT9;
wire[3:0]                        RSCRM4_B1ERR;
wire                             RSCRM4_B1ERR_EN;

wire[7:0]                        RSCRM1_DATA;
wire                             RSCRM1_DEN;
wire[8:0]                        RSCRM1_FMCNT270;
wire[3:0]                        RSCRM1_FMCNT9;
wire[3:0]                        RSCRM1_B1ERR;
wire                             RSCRM1_B1ERR_EN;

reg                              RMDSEL_MODE;
reg[7:0]                         RMDSEL_STM1_DATA;
reg                              RMDSEL_STM1_DEN;
reg[1:0]                         RMDSEL_STM1_FMCNT4;
reg[8:0]                         RMDSEL_STM1_FMCNT270;
reg[3:0]                         RMDSEL_STM1_FMCNT9;
reg[3:0]                         RMDSEL_STM1_DUPL_CNT;

wire[7:0]                        RMDSEL_STM4_DATA;
wire                             RMDSEL_STM4_DEN;
wire[1:0]                        RMDSEL_STM4_FMCNT4;
wire[8:0]                        RMDSEL_STM4_FMCNT270;
wire[3:0]                        RMDSEL_STM4_FMCNT9;

reg                              TMDSEL_MODE;
reg[7:0]                         TMDSEL_OUT_TDATA;
reg[1:0]                         TMDSEL_OUT_TFMCNT4;
reg[8:0]                         TMDSEL_OUT_TFMCNT270;
reg[3:0]                         TMDSEL_OUT_TFMCNT9;

wire[7:0]                        TJ0_TDATA;
wire[1:0]                        TJ0_TFMCNT4;
wire[8:0]                        TJ0_TFMCNT270;
wire[3:0]                        TJ0_TFMCNT9;

reg                              MPI_OOF;
reg[3:0]                         MPI_RPC_B1_ERRCNT;
reg                              MPI_RPC_B1_STROBE;

wire[3:0]                        MPI_RJ0_ADDR;
wire[7:0]                        MPI_RJ0_RD;
wire                             MPI_J0_MODE;
wire[3:0]                        MPI_TJ0_ADDR;
wire                             MPI_TJ0_WE;
wire[7:0]                        MPI_TJ0_WD;
wire[7:0]                        MPI_TJ0_RD;

FRM_DELMT4                                INST_FRM_DELMT4(
   .FRM_RESET                             ( FRM_RESET ),

   .FRM_RXCLK                             ( FRM_RXCLK ),
   .LINF_IN_RXD                           ( LINF_IN_RXD[7:0] ),
   .LINF_IN_RXDEN                         ( LINF_IN_RXDEN ),

   .DELMT4_OUT_FMCNT4                     ( DELMT4_FMCNT4[1:0] ),
   .DELMT4_OUT_FMCNT270                   ( DELMT4_FMCNT270[8:0] ),
   .DELMT4_OUT_FMCNT9                     ( DELMT4_FMCNT9[3:0] ),
   .DELMT4_OUT_DATA                       ( DELMT4_DATA[7:0] ),
   .DELMT4_OUT_DEN                        ( DELMT4_DEN ),
   .DELMT4_OUT_OOF                        ( DELMT4_OOF )
   );
FRM_RSCRM4                                INST_FRM_RSCRM4(
   .FRM_RESET                             ( FRM_RESET ),
   .FRM_RXCLK                             ( FRM_RXCLK ),

   .RSCRM4_IN_FMCNT4                      ( DELMT4_FMCNT4[1:0] ),
   .RSCRM4_IN_FMCNT270                    ( DELMT4_FMCNT270[8:0] ),
   .RSCRM4_IN_FMCNT9                      ( DELMT4_FMCNT9[3:0] ),
   .RSCRM4_IN_DATA                        ( DELMT4_DATA[7:0] ),
   .RSCRM4_IN_DEN                         ( DELMT4_DEN ),
   .RSCRM4_IN_OOF                         ( DELMT4_OOF ),

   .RSCRM4_OUT_DATA                       ( RSCRM4_DATA[7:0] ),
   .RSCRM4_OUT_DEN                        ( RSCRM4_DEN ),
   .RSCRM4_OUT_FMCNT4                     ( RSCRM4_FMCNT4[1:0] ),
   .RSCRM4_OUT_FMCNT270                   ( RSCRM4_FMCNT270[8:0] ),
   .RSCRM4_OUT_FMCNT9                     ( RSCRM4_FMCNT9[3:0] ),
   .RSCRM4_OUT_B1ERR                      ( RSCRM4_B1ERR[3:0] ),
   .RSCRM4_OUT_B1ERR_EN                   ( RSCRM4_B1ERR_EN )
   );


FRM_DELMT1                                INST_FRM_DELMT1(
   .FRM_RESET                             ( FRM_RESET ),

   .FRM_RXCLK                             ( FRM_RXCLK ),
   .LINF_IN_RXD                           ( LINF_IN_RXD[7:0] ),
   .LINF_IN_RXDEN                         ( LINF_IN_RXDEN ),

   .DELMT1_OUT_FMCNT270                   ( DELMT1_FMCNT270[8:0] ),
   .DELMT1_OUT_FMCNT9                     ( DELMT1_FMCNT9[3:0] ),
   .DELMT1_OUT_DATA                       ( DELMT1_DATA[7:0] ),
   .DELMT1_OUT_DEN                        ( DELMT1_DEN ),
   .DELMT1_OUT_OOF                        ( DELMT1_OOF )
   );
FRM_RSCRM1                                INST_FRM_RSCRM1(
   .FRM_RESET                             ( FRM_RESET ),
   .FRM_RXCLK                             ( FRM_RXCLK ),

   .RSCRM1_IN_FMCNT270                    ( DELMT1_FMCNT270[8:0] ),
   .RSCRM1_IN_FMCNT9                      ( DELMT1_FMCNT9[3:0] ),
   .RSCRM1_IN_DATA                        ( DELMT1_DATA[7:0] ),
   .RSCRM1_IN_DEN                         ( DELMT1_DEN ),
   .RSCRM1_IN_OOF                         ( DELMT1_OOF ),

   .RSCRM1_OUT_DATA                       ( RSCRM1_DATA[7:0] ),
   .RSCRM1_OUT_DEN                        ( RSCRM1_DEN ),
   .RSCRM1_OUT_FMCNT270                   ( RSCRM1_FMCNT270[8:0] ),
   .RSCRM1_OUT_FMCNT9                     ( RSCRM1_FMCNT9[3:0] ),
   .RSCRM1_OUT_B1ERR                      ( RSCRM1_B1ERR[3:0] ),
   .RSCRM1_OUT_B1ERR_EN                   ( RSCRM1_B1ERR_EN )
   );

always @( posedge FRM_RXCLK or posedge FRM_RESET ) begin
   if ( FRM_RESET==1'b1 )
      RMDSEL_MODE                              <= 1'b0;
   else
      RMDSEL_MODE                              <= GLBCF_LINF_MODE;
end

always @( posedge FRM_RXCLK or posedge FRM_RESET ) begin
   if ( FRM_RESET==1'b1 ) begin
      RMDSEL_STM1_DATA[7:0]                    <= 8'd0;
      RMDSEL_STM1_FMCNT270[8:0]                <= 9'd0;
      RMDSEL_STM1_FMCNT9[3:0]                  <= 4'd0;
   end
   else if ( RSCRM1_DEN==1'b1 ) begin
      RMDSEL_STM1_DATA[7:0]                    <= RSCRM1_DATA[7:0];
      RMDSEL_STM1_FMCNT270[8:0]                <= RSCRM1_FMCNT270[8:0];
      RMDSEL_STM1_FMCNT9[3:0]                  <= RSCRM1_FMCNT9[3:0];
   end
end
always @( posedge FRM_RXCLK or posedge FRM_RESET ) begin
   if ( FRM_RESET==1'b1 )
      RMDSEL_STM1_DUPL_CNT[3:0]                <= 4'd0;
   else begin
      if ( RSCRM1_DEN==1'b1 )
         RMDSEL_STM1_DUPL_CNT[3:0]             <= 4'd0;
      else if ( RMDSEL_STM1_DUPL_CNT[3:0]!=4'd15)
         RMDSEL_STM1_DUPL_CNT[3:0]             <= RMDSEL_STM1_DUPL_CNT[3:0] +4'd1;
   end
end
always @( RMDSEL_STM1_DUPL_CNT  ) begin
   RMDSEL_STM1_DEN                             <= ( RMDSEL_STM1_DUPL_CNT[3:0]==4'd0) || ( RMDSEL_STM1_DUPL_CNT[3:0]==4'd1) || ( RMDSEL_STM1_DUPL_CNT[3:0]==4'd2) || ( RMDSEL_STM1_DUPL_CNT[3:0]==4'd3);
   case ( RMDSEL_STM1_DUPL_CNT[3:0] )
   4'd0: RMDSEL_STM1_FMCNT4[1:0]               <= 2'd0;
   4'd1: RMDSEL_STM1_FMCNT4[1:0]               <= 2'd1;
   4'd2: RMDSEL_STM1_FMCNT4[1:0]               <= 2'd2;
   4'd3: RMDSEL_STM1_FMCNT4[1:0]               <= 2'd3;
   4'd4: RMDSEL_STM1_FMCNT4[1:0]               <= 2'd3;
   4'd5: RMDSEL_STM1_FMCNT4[1:0]               <= 2'd3;
   4'd6: RMDSEL_STM1_FMCNT4[1:0]               <= 2'd3;
   4'd7: RMDSEL_STM1_FMCNT4[1:0]               <= 2'd3;
   default:RMDSEL_STM1_FMCNT4[1:0]             <= 2'd3;
   endcase
end


  assign RMDSEL_STM4_DATA[7:0]     = RSCRM4_DATA[7:0];
  assign RMDSEL_STM4_DEN           = RSCRM4_DEN;
  assign RMDSEL_STM4_FMCNT4[1:0]   = RSCRM4_FMCNT4[1:0];
  assign RMDSEL_STM4_FMCNT270[8:0] = RSCRM4_FMCNT270[8:0];
  assign RMDSEL_STM4_FMCNT9[3:0]   = RSCRM4_FMCNT9[3:0];


always @( posedge FRM_RXCLK or posedge FRM_RESET ) begin
   if ( FRM_RESET==1'b1 ) begin
      FRM_OUT_RDATA[7:0]                       <= 8'd0;
      FRM_OUT_RDEN                             <= 1'd0;
      FRM_OUT_RFMCNT4[1:0]                     <= 2'd0;
      FRM_OUT_RFMCNT270[8:0]                   <= 9'd0;
      FRM_OUT_RFMCNT9[3:0]                     <= 4'd0;
   end
   else begin
      if ( RMDSEL_MODE==1'b1 ) begin     // STM-4
         FRM_OUT_RDATA[7:0]                    <= RMDSEL_STM4_DATA[7:0];
         FRM_OUT_RDEN                          <= RMDSEL_STM4_DEN;
         FRM_OUT_RFMCNT4[1:0]                  <= RMDSEL_STM4_FMCNT4[1:0];
         FRM_OUT_RFMCNT270[8:0]                <= RMDSEL_STM4_FMCNT270[8:0];
         FRM_OUT_RFMCNT9[3:0]                  <= RMDSEL_STM4_FMCNT9[3:0];
      end
      else begin
         FRM_OUT_RDATA[7:0]                    <= RMDSEL_STM1_DATA[7:0];
         FRM_OUT_RDEN                          <= RMDSEL_STM1_DEN;
         FRM_OUT_RFMCNT4[1:0]                  <= RMDSEL_STM1_FMCNT4[1:0];
         FRM_OUT_RFMCNT270[8:0]                <= RMDSEL_STM1_FMCNT270[8:0];
         FRM_OUT_RFMCNT9[3:0]                  <= RMDSEL_STM1_FMCNT9[3:0];
      end
   end
end

FRM_RJ0                                   INST_FRM_RJ0(
   .FRM_RESET                             ( FRM_RESET ),
   .FRM_RXCLK                             ( FRM_RXCLK ),

   .RJ0_IN_RDATA                          ( FRM_OUT_RDATA[7:0] ),
   .RJ0_IN_RDEN                           ( FRM_OUT_RDEN ),
   .RJ0_IN_RFMCNT4                        ( FRM_OUT_RFMCNT4[1:0] ),
   .RJ0_IN_RFMCNT270                      ( FRM_OUT_RFMCNT270[8:0] ),
   .RJ0_IN_RFMCNT9                        ( FRM_OUT_RFMCNT9[3:0] ),

   .MPI_CLK                               ( MPI_CLK ),
   .MPI_J0_MODE                           ( MPI_J0_MODE ),
   .MPI_RJ0_ADDR                          ( MPI_RJ0_ADDR[3:0] ),
   .MPI_RJ0_RD                            ( MPI_RJ0_RD[7:0] )

   );










always @( posedge FRM_TXCLK or posedge FRM_RESET ) begin
   if ( FRM_RESET==1'b1 )
      TMDSEL_MODE                              <= 1'b0;
   else
      TMDSEL_MODE                              <= GLBCF_LINF_MODE;
end

always @( posedge FRM_TXCLK or posedge FRM_RESET ) begin
   if ( FRM_RESET==1'b1 ) begin
      TMDSEL_OUT_TFMCNT4[1:0]                  <= 1'b0;
      TMDSEL_OUT_TFMCNT270[8:0]                <= 9'd0;
      TMDSEL_OUT_TFMCNT9[3:0]                  <= 4'd0;
      TMDSEL_OUT_TDATA[7:0]                    <= 8'd0;
   end
   else begin
      if ( TMDSEL_MODE==1'b1 ) begin
         TMDSEL_OUT_TFMCNT4[1:0]               <= FRM_IN_TFMCNT4[1:0];
         TMDSEL_OUT_TFMCNT270[8:0]             <= FRM_IN_TFMCNT270[8:0];
         TMDSEL_OUT_TFMCNT9[3:0]               <= FRM_IN_TFMCNT9[3:0];
         TMDSEL_OUT_TDATA[7:0]                 <= FRM_IN_TDATA[7:0];
      end
      else begin
         TMDSEL_OUT_TFMCNT4[1:0]               <= FRM_IN_TFMCNT4[1:0];
         TMDSEL_OUT_TFMCNT270[8:0]             <= FRM_IN_TFMCNT270[8:0];
         TMDSEL_OUT_TFMCNT9[3:0]               <= FRM_IN_TFMCNT9[3:0];
         if ( FRM_IN_TFMCNT4[1:0]==2'd0 )
            TMDSEL_OUT_TDATA[7:0]              <= FRM_IN_TDATA[7:0];
      end
   end
end


FRM_TJ0                                   INST_FRM_TJ0(
   .FRM_RESET                             ( FRM_RESET ),
   .FRM_TXCLK                             ( FRM_TXCLK ),

   .MPI_CLK                               ( MPI_CLK ),
   .MPI_J0_MODE                           ( MPI_J0_MODE ),
   .MPI_TJ0_ADDR                          ( MPI_TJ0_ADDR[3:0] ),
   .MPI_TJ0_WE                            ( MPI_TJ0_WE ),
   .MPI_TJ0_WD                            ( MPI_TJ0_WD[7:0] ),
   .MPI_TJ0_RD                            ( MPI_TJ0_RD[7:0] ),

   .TJ0_IN_TDATA                          ( TMDSEL_OUT_TFMCNT4[1:0] ),
   .TJ0_IN_TFMCNT4                        ( TMDSEL_OUT_TFMCNT270[8:0] ),
   .TJ0_IN_TFMCNT270                      ( TMDSEL_OUT_TFMCNT9[3:0] ),
   .TJ0_IN_TFMCNT9                        ( TMDSEL_OUT_TDATA[7:0] ),

   .TJ0_OUT_TDATA                         ( TJ0_TDATA[7:0] ),
   .TJ0_OUT_TFMCNT4                       ( TJ0_TFMCNT4[1:0] ),
   .TJ0_OUT_TFMCNT270                     ( TJ0_TFMCNT270[8:0] ),
   .TJ0_OUT_TFMCNT9                       ( TJ0_TFMCNT9[3:0] )
   );


FRM_TFRM                                  INST_FRM_TFRM(
   .FRM_RESET                             ( FRM_RESET ),
   .FRM_TXCLK                             ( FRM_TXCLK ),

   .GLBCF_LINF_MODE                       ( GLBCF_LINF_MODE ),

   .TFRM_IN_FMCNT4                        ( TJ0_TDATA[7:0] ),
   .TFRM_IN_FMCNT270                      ( TJ0_TFMCNT4[1:0] ),
   .TFRM_IN_FMCNT9                        ( TJ0_TFMCNT270[8:0] ),
   .TFRM_IN_DATA                          ( TJ0_TFMCNT9[3:0] ),

   .TFRM_OUT_DATA                         ( LINF_OUT_TXD[7:0] )
   );



// ++++++++++++++++++     select MPI OOF alarm and B1 errors counter with line interface mode  ++++++++++++++++++  //
always @( posedge FRM_RXCLK or posedge FRM_RESET ) begin
   if ( FRM_RESET==1'b1 ) begin
      MPI_OOF                                      <= 1'd0;
      MPI_RPC_B1_ERRCNT[3:0]                       <= 4'd0;
      MPI_RPC_B1_STROBE                            <= 1'b0;
   end
   else begin
      if ( TMDSEL_MODE==1'b1 ) begin
         MPI_OOF                                   <= DELMT4_OOF;
         MPI_RPC_B1_ERRCNT[3:0]                    <= RSCRM4_B1ERR[3:0];
         MPI_RPC_B1_STROBE                         <= RSCRM1_B1ERR_EN;
      end
      else begin
         MPI_OOF                                   <= DELMT1_OOF;
         MPI_RPC_B1_ERRCNT[3:0]                    <= RSCRM1_B1ERR[3:0];
         MPI_RPC_B1_STROBE                         <= RSCRM1_B1ERR_EN;
      end
   end
end




FRM_MPI                                   INST_FRM_MPI(
   .FRM_RESET                             ( FRM_RESET ),

   .MPI_CLK                               ( MPI_CLK ),
   .MPI_ADDR                              ( MPI_ADDR[7:0] ),
   .MPI_CS                                ( MPI_CS ),
   .MPI_WE                                ( MPI_WE ),
   .MPI_WD                                ( MPI_WD[15:0] ),
   .MPI_RD                                ( MPI_RD[15:0] ),
   .MPI_IRQ                               ( MPI_IRQ ),

   .MPI_TJ0_ADDR                          ( MPI_TJ0_ADDR[3:0] ),
   .MPI_TJ0_WE                            ( MPI_TJ0_WE ),
   .MPI_TJ0_WD                            ( MPI_TJ0_WD[7:0] ),
   .MPI_TJ0_RD                            ( MPI_TJ0_RD[7:0] ),

   .MPI_RJ0_ADDR                          ( MPI_RJ0_ADDR[3:0] ),
   .MPI_RJ0_RD                            ( MPI_RJ0_RD[7:0] ),

   .MPI_J0_MODE                           ( MPI_J0_MODE ),

   .MPI_RPC_B1_ERRCNT                     ( MPI_RPC_B1_ERRCNT[3:0] ),
   .MPI_RPC_B1_STROBE                     ( MPI_RPC_B1_STROBE ),

   .MPI_OOF                               ( MPI_OOF )
   );


endmodule
